import {CONTEXT_PATH} from "../global.js"
import {LOGOUT} from "../../../store/mutationTypes.js"
import {OK,NON_AUTHORITATIVE_INFORMATION,UNAUTHORIZED,METHOD_NOT_ALLOWED} from "../enum/HttpStatus.js"

/**
 * GET方法
 * @param url             请求的地址
 * @param data            请求的参数
 * @param menuFunctionId  功能ID
 * @param component       发起请求前的组件
 */
export function doGet(url, {data = {}, menuFunctionId = "", component} = {}) {
  return new Promise(function(resolve, reject) {
    //加入token标记和功能权限ID
    url += "?"+"tokenId="+localStorage.getItem("tokenId")+"&menuFunctionId="+menuFunctionId;
    //判断是否需要在链接上加入请求参数
    let requestParam = toRequestParam(data);
    if(requestParam) url += "&" +requestParam;
    //获取请求对象
    let request = getRequest({
      method: "get",
      resolve,
      reject,
      url,
      component
    });
    //发起连接
    request.send();
  });
}

/**
 * DELETE方法
 * @param url             请求的地址
 * @param data            请求的参数
 * @param menuFunctionId  功能Id
 * @param component       发起请求前的组件
 */
export function doDelete(url, {data = {}, menuFunctionId = "", component} = {}) {
  return new Promise(function(resolve, reject) {
    //加入token标记和功能权限ID
    url += "?"+"tokenId="+localStorage.getItem("tokenId")+"&menuFunctionId="+menuFunctionId;
    //创建请求
    let request = getRequest({
      method: "delete",
      resolve,
      reject,
      url,
      component
    });
    //按照JSON发送参数
    request.setRequestHeader("content-type", "application/json;charset=UTF-8");
    //发起请求
    request.send(JSON.stringify(data));
  });
}

/**
 * POST方法
 * @param url             请求的地址
 * @param data            发送的数据
 * @param menuFunctionId  发送的数据
 * @param component       发起请求前的组件
 */
export function doPost(url, {data = {}, menuFunctionId = "", component} = {}) {
  return new Promise(function(resolve, reject) {
    //加入token标记和功能权限ID
    // url += "?"+"tokenId="+localStorage.getItem("tokenId")+"&menuFunctionId="+menuFunctionId;
    //创建请求
    let request = getRequest({
      method: "post",
      resolve,
      reject,
      url,
      component
    });
    //按照JSON发送参数
    request.setRequestHeader("content-type", "application/json;charset=UTF-8");
    //发起请求
    request.send(JSON.stringify(data));
  });
}

/**  后缀请求参数 */
export function appendRequestParam(url, prop, value) {
  if(url) {
    //加密
    value = encodeURIComponent(value);
    //拼接
    if(url.includes("?")) {
      if(url.endsWith("?")) return url + prop + "="+value;
      else return url + "&"+prop+"="+value;
    } else {
      return url + "?" + prop + "=" + value;
    }
  } else {
    return "";
  }
}

/**
 * 获取请求对象
 * @param resolve               promise对象的resolve
 * @param reject                promise对象的reject
 * @param url                   url路径
 * @param method                请求方法
 * @param component             发起请求的组件
 * @returns {XMLHttpRequest}    返回请求对象
 */
function getRequest({
                      method,
                      resolve,
                      reject,
                      url,
                      component
                    }) {
  //所有的请求都加上服务器地址
  url = CONTEXT_PATH + url;
  //新建一个请求对象
  let request = new XMLHttpRequest();
  //打开连接
  request.open(method, url, true);
  //服务端均已JSON进行响应
  request.responseType = "json";
  //注册事件回调
  request.onload = function(e) {
    //如果状态不对，先返回一个错误的信息
    if(this.status !== OK) reject(new Error(this.status));
    //然后再根据错误类型，判断呈现给用户什么信息
    switch(this.status) {
      case OK:
        resolve(this.response);
        break;
      case NON_AUTHORITATIVE_INFORMATION:
        alert(component, "长时间未操作，请重新登录", action => {
          component.$store.commit(LOGOUT);
          window.location.reload();
        });
        break;
      case UNAUTHORIZED:
        alert(component, "无此数据访问权限");
        break;
      case METHOD_NOT_ALLOWED:
        alert(component, "无此操作权限");
        break;
      default:
        alert(component, "未知错误,错误码："+this.status+"，请上报管理员")
    }
  };

  //发生网络错误
  request.onerror = function(e) {
    reject(new Error(this.status));
    component.$alert("网络错误，请稍后再试", '提示', {
      confirmButtonText: '确定'
    });
  };
  //返回请求对象
  return request;
}

/**
 * 显示警告信息
 * @param component vue组件，为空则不显示
 * @param message   警告的消息
 * @param callback  确认按钮的回调事件
 */
function alert(component, message, callback) {
  component.$alert(message, '提示', {
    confirmButtonText: '确定',
    callback
  });
}

/**
 * 转换为请求参数
 * @param param   请求参数对象
 */
function toRequestParam(param) {
  let requestParam = "";
  Object.keys(param).forEach(k=>{
    if(param[k] === undefined || param[k] === null) {
      requestParam += k + "&";
    }else {
      requestParam += k + "=" + encodeURIComponent(param[k]) + "&";
    }
  });
  if (requestParam.endsWith("&")) return requestParam.substring(0, requestParam.length-1);
  else return requestParam;
}



// WEBPACK FOOTER //
// ./src/assets/js/utils/RequestUtils.js
